package ij.hkust;

import ij.hkust.gui.laserCtr.STORM.CameraLabel;
import ij.hkust.gui.laserCtr.STORM.OneFrame;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * user settings that will be saved into a file. each time we change the settings, we will save the settings into the setting configuration file when the window is closing.
 * @author liuquan
 *
 */
public class UserSettings {
	public static String fileName;
	
	//+++++++EPI settings
//	public static int epiLaserCount;//the count of laser
	public static List<String> epiLasers = new ArrayList<String>();//the lasers 
	public static List<String> epiLaserInt = new ArrayList<String>();//the intensity of each laser
	
	//++++++++DSTORM settings these settings may be copied from epi
//	public static int dsLaserCount;//the count of laser
	public static List<String> dstLasers = new ArrayList<String>();//the lasers 
	public static List<String> dstLaserInt = new ArrayList<String>();//the intensity of each laser
	
	//++++++STORM settings
//	public static int stLaserCount;//laser count
	public static List<String> stLasers = new ArrayList<String>();//laser'ID list
	public static Map<String, ArrayList<OneFrame>> stFrames =new HashMap<String,ArrayList<OneFrame>>();//laser frames
	public static List<CameraLabel> stCamera = new ArrayList<CameraLabel>();//the camera control cmd

	private static Properties settings = new Properties();//the properties to load and save the settings
	
	/**
	 * load settings from the file.here we can know the home dir of the software
	 * @param file
	 */

	public static void loadSettings(String file){
//		System.out.println(file);
		fileName = file;
//		IJ.error(Prefs.getHomeDir());
		try {
			//load the setting file, and 
			settings.load(new FileInputStream(fileName));
			
			//TODO load other settings
			
			
			//########read EPI settings
			int epiCount;
			if(settings.getProperty("epi_count") == null){
				epiCount = 0;
			}else{
				epiCount = Integer.parseInt(settings.getProperty("epi_count"));
			}
			 
			for(int i=0;i<epiCount;i++){
				epiLasers.add(settings.getProperty("epi_laser_" + i));
				epiLaserInt.add(settings.getProperty("epi_int_" + i));
			}
			//########read DAOSTORM settings
			int dstCount;
			if(settings.getProperty("dst_count") == null){
				dstCount = 0;
			}else{
				dstCount = Integer.parseInt(settings.getProperty("dst_count"));
			}
			
			for(int i=0;i<dstCount;i++){
				dstLasers.add(settings.getProperty("dst_laser_" + i));
				dstLaserInt.add(settings.getProperty("dst_int_" + i));
			}
			
			//###########read storm settings###################
			int stCount;
			if(settings.getProperty("storm_count") == null){
				stCount = 0;
			}else{
				stCount = Integer.parseInt(settings.getProperty("storm_count"));
			}
			//read lasers and frames
			for(int i=0;i<stCount;i++){
				String tmpLaser = settings.getProperty("ds_laser_" + i);
				stLasers.add(tmpLaser);
				//read frames for each laser
				ArrayList<OneFrame> tmpFrames = new ArrayList<OneFrame>();
				int frameCount = Integer.parseInt(settings.getProperty("ds_laser_" + i + "_count"));
				int countTime = 0;
				for(int j=0;j<frameCount;j++){
					OneFrame tmpFrame = new OneFrame();
					tmpFrame.setTime(Integer.parseInt(settings.getProperty("ds_" + i +"_" + j + "_time")));
					tmpFrame.setIntensity(Integer.parseInt(settings.getProperty("ds_" + i +"_" + j + "_int")));
					tmpFrame.setCountTime(countTime);
					countTime += tmpFrame.getTime();
					tmpFrames.add(tmpFrame);
				}
				stFrames.put(tmpLaser, tmpFrames);
				
			}
			//read camera settings
			int cameraCount;
			if(settings.getProperty("storm_camera_count") == null){
				cameraCount = 0;
			}else{
				cameraCount = Integer.parseInt(settings.getProperty("storm_camera_count"));
			}
			for(int i=0;i<cameraCount;i++){
				CameraLabel tmp = new CameraLabel();
				tmp.setTime(Integer.parseInt(settings.getProperty("ds_ca_" + i +"_time")));
				tmp.setChannel(Integer.parseInt(settings.getProperty("ds_ca_" + i +"_channel")));
				if(settings.getProperty("ds_ca_" + i +"_imgcount") != null)
					tmp.setImageCount(Integer.parseInt(settings.getProperty("ds_ca_" + i +"_imgcount")));
				tmp.setIndex(i);
				tmp.setUse(Boolean.parseBoolean(settings.getProperty("ds_ca_" + i +"_use")));
				stCamera.add(tmp);
			}
			//##################END of storm setting#############
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * write all the settings into the settings file
	 */
	public static void saveSettings(){
		Properties saver = new Properties();
		//TODO copy the useful old settings here
		
		//add the new settings to the properties
		
		//#########the EPI settings#############
		saver.put("epi_count", epiLasers.size() + "");
		for(int i=0;i<epiLasers.size();i++){
			saver.put("epi_laser_" + i,epiLasers.get(i));
			saver.put("epi_int_" + i, epiLaserInt.get(i));
		}
		
		//#########the DAOSTORM settings#############
		saver.put("dst_count", dstLasers.size() + "");
		for (int i = 0; i < dstLasers.size(); i++) {
			saver.put("dst_laser_" + i, dstLasers.get(i));
			saver.put("dst_int_" + i, dstLaserInt.get(i));
		}
		
		//########## the storm settings###########
		saver.put("storm_count", stLasers.size() + "");
		for(int i=0;i<stLasers.size();i++){
			saver.put("ds_laser_" + i, stLasers.get(i));
			ArrayList<OneFrame> tmpFrame = stFrames.get(stLasers.get(i));
			if(tmpFrame != null){
				//here we save each laser's frame into the setting file, and we
				saver.put("ds_laser_" + i + "_count", tmpFrame.size() + "");
				for(int j=0;j<tmpFrame.size() ;j++){
					saver.put("ds_" + i +"_" + j + "_time", tmpFrame.get(j).getTime() + "");
					saver.put("ds_" + i +"_" + j + "_int", tmpFrame.get(j).getIntensity() + "");
				}
			}
		}
		//storm camera
		saver.put("storm_camera_count", stCamera.size() + "");
		for(int i=0;i<stCamera.size();i++){
			saver.put("ds_ca_" + i +"_time", stCamera.get(i).getTime() + "");
			saver.put("ds_ca_" + i +"_channel", stCamera.get(i).getChannel() + "");
			saver.put("ds_ca_" + i +"_use", stCamera.get(i).isUse() + "");
			saver.put("ds_ca_" + i +"_imgcount", stCamera.get(i).getImageCount() + "");
			
		}
		
		//save to the file
		try {
			OutputStream fos = new FileOutputStream(fileName);
			saver.store(fos, "save the user settings");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @param laser
	 * @param power
	 */
	public static void addEpiCtr(String laser,String power){
		if(laser != null){
			epiLasers.add(laser);
			epiLaserInt.add(power);
//			epiLaserCount++;
		}
	}
	/**
	 * 
	 * @param laser
	 * @param power
	 */
	public static void addDstCtr(String laser,String power){
		if(laser == null || power == null){
			//TODO: do something
		}else{
			dstLasers.add(laser);
			dstLaserInt.add(power);
		}
	}

	/**
	 * add one frame to storm use
	 * @param laser
	 * @param frames
	 */
	public static void addStormCtr(String laser, ArrayList<OneFrame> frames){
		if(laser != null){
			stLasers.add(laser);
			stFrames.put(laser, frames);
//			stLaserCount++;
		}else{
			//TODO do something
		}
	}
	
	public static void addStormCamera(CameraLabel ca){
		if(ca == null){
			return;
		}else{
			stCamera.add(ca);
		}
	}
}
